﻿/**
 * @file sm2.h
 * @brief Header file for SM2 cryptographic operations.
 *
 * This header file contains declarations and definitions necessary for performing SM2 cryptographic operations.
 */

#ifndef peace_sm2_H
#define peace_sm2_H

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "sm2_common.h"

#ifdef __cplusplus
extern "C"
{
#endif

/**
 * @brief Minimum plaintext size for SM2 operations.
 *
 * This macro defines the minimum size of the plaintext that can be processed by SM2 functions.
 */
#define peace_sm2_MIN_PLAINTEXT_SIZE 1

/**
 * @brief Maximum plaintext size for SM2 operations.
 *
 * This macro defines the maximum size of the plaintext that can be processed by SM2 functions.
 */
#define peace_sm2_MAX_PLAINTEXT_SIZE 255

	/**
	 * @brief Type definition for a big number (BN).
	 *
	 * This type represents a big number used in SM2 operations.
	 */
	typedef uint64_t peace_sm2_BN[8];

	/**
	 * @brief Standard return type for functions.
	 *
	 * This type is used as the standard return type for functions, where E_OK indicates success and E_NOT_OK indicates failure.
	 */
	typedef uint8_t Std_ReturnType;

	/**
	 * @brief Type definition for a field element over Fp.
	 *
	 * This type represents a field element over Fp used in SM2 operations.
	 */
	typedef peace_sm2_BN peace_sm2_Fp;

	/**
	 * @brief Type definition for a field element over Fn.
	 *
	 * This type represents a field element over Fn used in SM2 operations.
	 */
	typedef peace_sm2_BN peace_sm2_Fn;

	/**
	 * @brief Structure representing a Jacobian point.
	 *
	 * This structure holds the coordinates of a point in Jacobian form used in elliptic curve operations.
	 */
	typedef struct
	{
		peace_sm2_BN X; /**< X coordinate of the Jacobian point. */
		peace_sm2_BN Y; /**< Y coordinate of the Jacobian point. */
		peace_sm2_BN Z; /**< Z coordinate of the Jacobian point. */
	} peace_sm2_JACOBIAN_POINT;

	/**
	 * @brief Type definition for a big number represented as a byte array.
	 *
	 * This type represents a big number as a byte array of fixed length.
	 */
	typedef uint8_t peace_sm2_bn_t[32];

	/**
	 * @brief Structure representing an affine point.
	 *
	 * This structure holds the coordinates of a point in affine form used in elliptic curve operations.
	 */
	typedef struct
	{
		uint8_t x[32]; /**< X coordinate of the affine point. */
		uint8_t y[32]; /**< Y coordinate of the affine point. */
	} peace_sm2_POINT;

	/**
	 * @brief Structure representing an SM2 key pair.
	 *
	 * This structure holds both the public and private keys for SM2 operations.
	 */
	typedef struct
	{
		peace_sm2_POINT public_key; /**< Public key in affine form. */
		uint8_t private_key[32];	/**< Private key as a byte array. */
	} peace_sm2_KEY;

	/**
	 * @brief Structure representing an SM2 signature.
	 *
	 * This structure holds the components of an SM2 signature.
	 */
	typedef struct
	{
		uint8_t r[32]; /**< R component of the signature. */
		uint8_t s[32]; /**< S component of the signature. */
	} peace_sm2_SIGNATURE;

	/**
	 * @brief Enumerations for different sizes of SM2 signatures.
	 *
	 * These enumerations define the possible sizes of SM2 signatures.
	 */
	enum
	{
		peace_sm2_signature_compact_size = 70, /**< Compact size of the signature. */
		peace_sm2_signature_typical_size = 71, /**< Typical size of the signature. */
		peace_sm2_signature_max_size = 72	   /**< Maximum size of the signature. */
	};

	/**
	 * @brief Structure representing the context for SM2 signing.
	 *
	 * This structure holds the context information required for SM2 signing operations.
	 */
	typedef struct
	{
		peace_sm3_CTX peace_sm3_ctx; /**< Context for SM3 hashing. */
		peace_sm2_KEY key;			 /**< SM2 key pair. */
	} peace_sm2_SIGN_CTX;

	/**
	 * @brief Structure representing an SM2 ciphertext.
	 *
	 * This structure holds the encrypted message along with its associated metadata.
	 */
	typedef struct
	{
		peace_sm2_POINT point;							  /**< Affine point used in encryption. */
		uint8_t hash[32];								  /**< Hash of the plaintext. */
		uint8_t ciphertext_size;						  /**< Size of the ciphertext. */
		uint8_t ciphertext[peace_sm2_MAX_PLAINTEXT_SIZE]; /**< Ciphertext data. */
	} peace_sm2_CIPHERTEXT;

	/**
	 * @brief Enumerations for different sizes of SM2 ciphertext points.
	 *
	 * These enumerations define the possible sizes of the affine points used in SM2 ciphertexts.
	 */
	enum
	{
		peace_sm2_ciphertext_compact_point_size = 68, /**< Compact size of the ciphertext point. */
		peace_sm2_ciphertext_typical_point_size = 69, /**< Typical size of the ciphertext point. */
		peace_sm2_ciphertext_max_point_size = 70	  /**< Maximum size of the ciphertext point. */
	};
/**
 * @brief Defines the size of the big number (BN) structure.
 *
 * This macro defines the size of the `peace_sm2_BN` structure.
 */
#define peace_sm2_sizeof_bn (sizeof(peace_sm2_BN))

	/**
	 * @brief Verifies an SM2 signature.
	 *
	 * This function verifies an SM2 signature using the provided buffer, private key, public key, and signature.
	 *
	 * @param[in] buf Pointer to the buffer containing the data to be verified.
	 * @param[in] bufLength Length of the buffer.
	 * @param[in] privateKey Pointer to the private key.
	 * @param[in] publicKey Pointer to the public key.
	 * @param[out] sigVerifyResult Pointer to the result of the signature verification.
	 * @param[in] sigLen Length of the signature.
	 * @return Std_ReturnType Returns E_OK on success, E_NOT_OK on failure.
	 */
	Std_ReturnType peace_sm2_verify(uint8_t *buf, uint32_t bufLength, uint8_t *privateKey, uint8_t *publicKey, uint8_t *sigVerifyResult, size_t sigLen);

	/**
	 * @brief Signs a buffer using the SM2 algorithm.
	 *
	 * This function signs the provided buffer using the SM2 algorithm with the given private key and public key.
	 *
	 * @param[in] buf Pointer to the buffer containing the data to be signed.
	 * @param[in] buf_length Length of the buffer.
	 * @param[in] Private_Key Pointer to the private key.
	 * @param[in] Publickey Pointer to the public key.
	 * @param[out] Sig_Result Pointer to the result of the signing operation.
	 * @param[out] Sig_R Pointer to the R component of the signature.
	 * @param[out] Sig_S Pointer to the S component of the signature.
	 * @param[out] siglen Pointer to the length of the signature.
	 * @return Std_ReturnType Returns E_OK on success, E_NOT_OK on failure.
	 */
	Std_ReturnType peace_sm2_sign(uint8_t *buf, uint32_t buf_length, uint8_t *Private_Key, uint8_t *Publickey, uint8_t *Sig_Result, uint8_t *Sig_R, uint8_t *Sig_S, size_t *siglen);

	/**
	 * @brief Checks if a big number is zero.
	 *
	 * This function checks if the given big number is zero.
	 *
	 * @param[in] a Big number to check.
	 * @return int Returns 1 if the big number is zero, 0 otherwise.
	 */
	int peace_sm2_bn_is_zero(const peace_sm2_BN a);

	/**
	 * @brief Checks if a big number is one.
	 *
	 * This function checks if the given big number is one.
	 *
	 * @param[in] a Big number to check.
	 * @return int Returns 1 if the big number is one, 0 otherwise.
	 */
	int peace_sm2_bn_is_one(const peace_sm2_BN a);

	/**
	 * @brief Checks if a big number is odd.
	 *
	 * This function checks if the given big number is odd.
	 *
	 * @param[in] a Big number to check.
	 * @return int Returns 1 if the big number is odd, 0 otherwise.
	 */
	int peace_sm2_bn_is_odd(const peace_sm2_BN a);

	/**
	 * @brief Compares two big numbers.
	 *
	 * This function compares two big numbers.
	 *
	 * @param[in] a First big number.
	 * @param[in] b Second big number.
	 * @return int Returns -1 if a < b, 0 if a == b, 1 if a > b.
	 */
	int peace_sm2_bn_cmp(const peace_sm2_BN a, const peace_sm2_BN b);

	/**
	 * @brief Converts a hexadecimal string to a big number.
	 *
	 * This function converts a hexadecimal string to a big number.
	 *
	 * @param[out] r Resultant big number.
	 * @param[in] hex Hexadecimal string.
	 * @return int Returns 0 on success, non-zero on failure.
	 */
	int peace_sm2_bn_from_hex(peace_sm2_BN r, const char hex[64]);

	/**
	 * @brief Converts an ASN.1 integer to a big number.
	 *
	 * This function converts an ASN.1 integer to a big number.
	 *
	 * @param[out] r Resultant big number.
	 * @param[in] d Pointer to the ASN.1 integer data.
	 * @param[in] dlen Length of the ASN.1 integer data.
	 * @return int Returns 0 on success, non-zero on failure.
	 */
	int peace_sm2_bn_from_asn1_integer(peace_sm2_BN r, const uint8_t *d, size_t dlen);

	/**
	 * @brief Prints a big number to a file.
	 *
	 * This function prints a big number to a file with the specified format and indentation.
	 *
	 * @param[in] fp File pointer.
	 * @param[in] fmt Format specifier.
	 * @param[in] ind Indentation level.
	 * @param[in] label Label for the big number.
	 * @param[in] a Big number to print.
	 * @return int Returns 0 on success, non-zero on failure.
	 */
	int peace_sm2_bn_print(FILE *fp, int fmt, int ind, const char *label, const peace_sm2_BN a);

	/**
	 * @brief Performs a right shift on a big number.
	 *
	 * This function performs a right shift on a big number by the specified number of bits.
	 *
	 * @param[out] ret Resultant big number after the right shift.
	 * @param[in] a Big number to be shifted.
	 * @param[in] nbits Number of bits to shift.
	 * @return int Returns 0 on success, non-zero on failure.
	 */
	int peace_sm2_bn_rshift(peace_sm2_BN ret, const peace_sm2_BN a, unsigned int nbits);

	/**
	 * @brief Converts a big number to a byte array.
	 *
	 * This function converts a big number to a byte array of fixed length.
	 *
	 * @param[in] a Big number to convert.
	 * @param[out] out Byte array to store the result.
	 */
	void peace_sm2_bn_to_bytes(const peace_sm2_BN a, uint8_t out[32]);

	/**
	 * @brief Converts a byte array to a big number.
	 *
	 * This function converts a byte array of fixed length to a big number.
	 *
	 * @param[out] r Resultant big number.
	 * @param[in] in Byte array to convert.
	 */
	void peace_sm2_bn_from_bytes(peace_sm2_BN r, const uint8_t in[32]);

	/**
	 * @brief Converts a big number to a hexadecimal string.
	 *
	 * This function converts a big number to a hexadecimal string.
	 *
	 * @param[in] a Big number to convert.
	 * @param[out] hex Hexadecimal string to store the result.
	 */
	void peace_sm2_bn_to_hex(const peace_sm2_BN a, char hex[64]);

	/**
	 * @brief Converts a big number to a bit string.
	 *
	 * This function converts a big number to a bit string.
	 *
	 * @param[in] a Big number to convert.
	 * @param[out] bits Bit string to store the result.
	 */
	void peace_sm2_bn_to_bits(const peace_sm2_BN a, char bits[256]);

	/**
	 * @brief Sets a big number to a word value.
	 *
	 * This function sets a big number to a specified word value.
	 *
	 * @param[out] r Resultant big number.
	 * @param[in] a Word value to set.
	 */
	void peace_sm2_bn_set_word(peace_sm2_BN r, uint32_t a);

	/**
	 * @brief Adds two big numbers.
	 *
	 * This function adds two big numbers.
	 *
	 * @param[out] r Resultant big number after addition.
	 * @param[in] a First big number.
	 * @param[in] b Second big number.
	 */
	void peace_sm2_bn_add(peace_sm2_BN r, const peace_sm2_BN a, const peace_sm2_BN b);

	/**
	 * @brief Subtracts one big number from another.
	 *
	 * This function subtracts the second big number from the first.
	 *
	 * @param[out] ret Resultant big number after subtraction.
	 * @param[in] a First big number.
	 * @param[in] b Second big number.
	 */
	void peace_sm2_bn_sub(peace_sm2_BN ret, const peace_sm2_BN a, const peace_sm2_BN b);

	/**
	 * @brief Generates a random big number within a specified range.
	 *
	 * This function generates a random big number within the specified range.
	 *
	 * @param[out] r Resultant random big number.
	 * @param[in] range Upper bound of the range.
	 * @return int Returns 0 on success, non-zero on failure.
	 */
	int peace_sm2_bn_rand_range(peace_sm2_BN r, const peace_sm2_BN range);

	/**
	 * @brief Adds two field elements in Fp.
	 *
	 * This function performs the addition of two field elements in the finite field Fp.
	 *
	 * @param[out] r Resultant field element after addition.
	 * @param[in] a First field element.
	 * @param[in] b Second field element.
	 */
	void peace_sm2_fp_add(peace_sm2_Fp r, const peace_sm2_Fp a, const peace_sm2_Fp b);

	/**
	 * @brief Subtracts one field element from another in Fp.
	 *
	 * This function performs the subtraction of the second field element from the first in the finite field Fp.
	 *
	 * @param[out] r Resultant field element after subtraction.
	 * @param[in] a First field element.
	 * @param[in] b Second field element.
	 */
	void peace_sm2_fp_sub(peace_sm2_Fp r, const peace_sm2_Fp a, const peace_sm2_Fp b);

	/**
	 * @brief Multiplies two field elements in Fp.
	 *
	 * This function performs the multiplication of two field elements in the finite field Fp.
	 *
	 * @param[out] r Resultant field element after multiplication.
	 * @param[in] a First field element.
	 * @param[in] b Second field element.
	 */
	void peace_sm2_fp_mul(peace_sm2_Fp r, const peace_sm2_Fp a, const peace_sm2_Fp b);

	/**
	 * @brief Exponentiates a field element in Fp.
	 *
	 * This function raises a field element to the power of another field element in the finite field Fp.
	 *
	 * @param[out] r Resultant field element after exponentiation.
	 * @param[in] a Base field element.
	 * @param[in] e Exponent field element.
	 */
	void peace_sm2_fp_exp(peace_sm2_Fp r, const peace_sm2_Fp a, const peace_sm2_Fp e);

	/**
	 * @brief Doubles a field element in Fp.
	 *
	 * This function doubles the specified field element in the finite field Fp.
	 *
	 * @param[out] r Resultant field element after doubling.
	 * @param[in] a Field element to be doubled.
	 */
	void peace_sm2_fp_dbl(peace_sm2_Fp r, const peace_sm2_Fp a);

	/**
	 * @brief Triples a field element in Fp.
	 *
	 * This function triples the specified field element in the finite field Fp.
	 *
	 * @param[out] r Resultant field element after tripling.
	 * @param[in] a Field element to be tripled.
	 */
	void peace_sm2_fp_tri(peace_sm2_Fp r, const peace_sm2_Fp a);

	/**
	 * @brief Divides a field element by 2 in Fp.
	 *
	 * This function divides the specified field element by 2 in the finite field Fp.
	 *
	 * @param[out] r Resultant field element after division by 2.
	 * @param[in] a Field element to be divided.
	 */
	void peace_sm2_fp_div2(peace_sm2_Fp r, const peace_sm2_Fp a);

	/**
	 * @brief Negates a field element in Fp.
	 *
	 * This function negates the specified field element in the finite field Fp.
	 *
	 * @param[out] r Resultant field element after negation.
	 * @param[in] a Field element to be negated.
	 */
	void peace_sm2_fp_neg(peace_sm2_Fp r, const peace_sm2_Fp a);

	/**
	 * @brief Squares a field element in Fp.
	 *
	 * This function squares the specified field element in the finite field Fp.
	 *
	 * @param[out] r Resultant field element after squaring.
	 * @param[in] a Field element to be squared.
	 */
	void peace_sm2_fp_sqr(peace_sm2_Fp r, const peace_sm2_Fp a);

	/**
	 * @brief Inverts a field element in Fp.
	 *
	 * This function computes the multiplicative inverse of the specified field element in the finite field Fp.
	 *
	 * @param[out] r Resultant field element after inversion.
	 * @param[in] a Field element to be inverted.
	 */
	void peace_sm2_fp_inv(peace_sm2_Fp r, const peace_sm2_Fp a);

	/**
	 * @brief Adds two field elements in Fn.
	 *
	 * This function performs the addition of two field elements in the finite field Fn.
	 *
	 * @param[out] r Resultant field element after addition.
	 * @param[in] a First field element.
	 * @param[in] b Second field element.
	 */
	void peace_sm2_fn_add(peace_sm2_Fn r, const peace_sm2_Fn a, const peace_sm2_Fn b);

	/**
	 * @brief Subtracts one field element from another in Fn.
	 *
	 * This function performs the subtraction of the second field element from the first in the finite field Fn.
	 *
	 * @param[out] r Resultant field element after subtraction.
	 * @param[in] a First field element.
	 * @param[in] b Second field element.
	 */
	void peace_sm2_fn_sub(peace_sm2_Fn r, const peace_sm2_Fn a, const peace_sm2_Fn b);

	/**
	 * @brief Multiplies two field elements in Fn.
	 *
	 * This function performs the multiplication of two field elements in the finite field Fn.
	 *
	 * @param[out] r Resultant field element after multiplication.
	 * @param[in] a First field element.
	 * @param[in] b Second field element.
	 */
	void peace_sm2_fn_mul(peace_sm2_Fn r, const peace_sm2_Fn a, const peace_sm2_Fn b);

	/**
	 * @brief Multiplies a field element by a word in Fn.
	 *
	 * This function multiplies a field element by a single-word integer in the finite field Fn.
	 *
	 * @param[out] r Resultant field element after multiplication.
	 * @param[in] a Field element.
	 * @param[in] b Single-word integer.
	 */
	void peace_sm2_fn_mul_word(peace_sm2_Fn r, const peace_sm2_Fn a, uint32_t b);

	/**
	 * @brief Exponentiates a field element in Fn.
	 *
	 * This function raises a field element to the power of another field element in the finite field Fn.
	 *
	 * @param[out] r Resultant field element after exponentiation.
	 * @param[in] a Base field element.
	 * @param[in] e Exponent field element.
	 */
	void peace_sm2_fn_exp(peace_sm2_Fn r, const peace_sm2_Fn a, const peace_sm2_Fn e);

	/**
	 * @brief Negates a field element in Fn.
	 *
	 * This function negates the specified field element in the finite field Fn.
	 *
	 * @param[out] r Resultant field element after negation.
	 * @param[in] a Field element to be negated.
	 */
	void peace_sm2_fn_neg(peace_sm2_Fn r, const peace_sm2_Fn a);

	/**
	 * @brief Squares a field element in Fn.
	 *
	 * This function squares the specified field element in the finite field Fn.
	 *
	 * @param[out] r Resultant field element after squaring.
	 * @param[in] a Field element to be squared.
	 */
	void peace_sm2_fn_sqr(peace_sm2_Fn r, const peace_sm2_Fn a);

	/**
	 * @brief Inverts a field element in Fn.
	 *
	 * This function computes the multiplicative inverse of the specified field element in the finite field Fn.
	 *
	 * @param[out] r Resultant field element after inversion.
	 * @param[in] a Field element to be inverted.
	 */
	void peace_sm2_fn_inv(peace_sm2_Fn r, const peace_sm2_Fn a);

	/**
	 * @brief Generates a random field element in Fn.
	 *
	 * This function generates a random field element in the finite field Fn.
	 *
	 * @param[out] r Randomly generated field element.
	 * @return int Returns 0 on success, non-zero on failure.
	 */
	int peace_sm2_fn_rand(peace_sm2_Fn r);
	/**
	 * @brief Initializes a Jacobian point.
	 *
	 * This function initializes the specified Jacobian point to represent the point at infinity.
	 *
	 * @param[out] R Pointer to the Jacobian point to be initialized.
	 */
	void peace_sm2_jacobian_point_init(peace_sm2_JACOBIAN_POINT *R);

	/**
	 * @brief Sets the X and Y coordinates of a Jacobian point.
	 *
	 * This function sets the X and Y coordinates of the specified Jacobian point.
	 *
	 * @param[out] R Pointer to the Jacobian point whose coordinates will be set.
	 * @param[in] x The X coordinate as a big number.
	 * @param[in] y The Y coordinate as a big number.
	 */
	void peace_sm2_jacobian_point_set_xy(peace_sm2_JACOBIAN_POINT *R, const peace_sm2_BN x, const peace_sm2_BN y);

	/**
	 * @brief Retrieves the X and Y coordinates of a Jacobian point.
	 *
	 * This function retrieves the X and Y coordinates from the specified Jacobian point.
	 *
	 * @param[in] P Pointer to the Jacobian point from which coordinates will be retrieved.
	 * @param[out] x Buffer to store the X coordinate as a big number.
	 * @param[out] y Buffer to store the Y coordinate as a big number.
	 */
	void peace_sm2_jacobian_point_get_xy(const peace_sm2_JACOBIAN_POINT *P, peace_sm2_BN x, peace_sm2_BN y);

	/**
	 * @brief Negates a Jacobian point.
	 *
	 * This function computes the negation of the specified Jacobian point.
	 *
	 * @param[out] R Pointer to the Jacobian point that will store the result.
	 * @param[in] P Pointer to the Jacobian point to be negated.
	 */
	void peace_sm2_jacobian_point_neg(peace_sm2_JACOBIAN_POINT *R, const peace_sm2_JACOBIAN_POINT *P);

	/**
	 * @brief Doubles a Jacobian point.
	 *
	 * This function computes the doubling of the specified Jacobian point.
	 *
	 * @param[out] R Pointer to the Jacobian point that will store the result.
	 * @param[in] P Pointer to the Jacobian point to be doubled.
	 */
	void peace_sm2_jacobian_point_dbl(peace_sm2_JACOBIAN_POINT *R, const peace_sm2_JACOBIAN_POINT *P);

	/**
	 * @brief Adds two Jacobian points.
	 *
	 * This function computes the addition of two specified Jacobian points.
	 *
	 * @param[out] R Pointer to the Jacobian point that will store the result.
	 * @param[in] P Pointer to the first Jacobian point.
	 * @param[in] Q Pointer to the second Jacobian point.
	 */
	void peace_sm2_jacobian_point_add(peace_sm2_JACOBIAN_POINT *R, const peace_sm2_JACOBIAN_POINT *P, const peace_sm2_JACOBIAN_POINT *Q);

	/**
	 * @brief Subtracts one Jacobian point from another.
	 *
	 * This function computes the subtraction of the second Jacobian point from the first.
	 *
	 * @param[out] R Pointer to the Jacobian point that will store the result.
	 * @param[in] P Pointer to the first Jacobian point.
	 * @param[in] Q Pointer to the second Jacobian point.
	 */
	void peace_sm2_jacobian_point_sub(peace_sm2_JACOBIAN_POINT *R, const peace_sm2_JACOBIAN_POINT *P, const peace_sm2_JACOBIAN_POINT *Q);

	/**
	 * @brief Multiplies a Jacobian point by a scalar.
	 *
	 * This function multiplies the specified Jacobian point by a scalar value.
	 *
	 * @param[out] R Pointer to the Jacobian point that will store the result.
	 * @param[in] k Scalar value as a big number.
	 * @param[in] P Pointer to the Jacobian point to be multiplied.
	 */
	void peace_sm2_jacobian_point_mul(peace_sm2_JACOBIAN_POINT *R, const peace_sm2_BN k, const peace_sm2_JACOBIAN_POINT *P);

	/**
	 * @brief Converts a Jacobian point to a byte array.
	 *
	 * This function converts the specified Jacobian point to a byte array representation.
	 *
	 * @param[in] P Pointer to the Jacobian point to be converted.
	 * @param[out] out Buffer to store the byte array representation (64 bytes).
	 */
	void peace_sm2_jacobian_point_to_bytes(const peace_sm2_JACOBIAN_POINT *P, uint8_t out[64]);

	/**
	 * @brief Converts a byte array to a Jacobian point.
	 *
	 * This function converts a byte array representation to a Jacobian point.
	 *
	 * @param[out] P Pointer to the Jacobian point that will store the result.
	 * @param[in] in Byte array representation (64 bytes) of the Jacobian point.
	 */
	void peace_sm2_jacobian_point_from_bytes(peace_sm2_JACOBIAN_POINT *P, const uint8_t in[64]);

	/**
	 * @brief Multiplies the generator point by a scalar.
	 *
	 * This function multiplies the generator point by a scalar value.
	 *
	 * @param[out] R Pointer to the Jacobian point that will store the result.
	 * @param[in] k Scalar value as a big number.
	 */
	void peace_sm2_jacobian_point_mul_generator(peace_sm2_JACOBIAN_POINT *R, const peace_sm2_BN k);

	/**
	 * @brief Computes a linear combination of two Jacobian points.
	 *
	 * This function computes the result of t*P + s*G, where G is the generator point.
	 *
	 * @param[out] R Pointer to the Jacobian point that will store the result.
	 * @param[in] t Scalar multiplier for point P as a big number.
	 * @param[in] P Pointer to the first Jacobian point.
	 * @param[in] s Scalar multiplier for the generator point as a big number.
	 */
	void peace_sm2_jacobian_point_mul_sum(peace_sm2_JACOBIAN_POINT *R, const peace_sm2_BN t, const peace_sm2_JACOBIAN_POINT *P, const peace_sm2_BN s);

	/**
	 * @brief Converts a hexadecimal string to a Jacobian point.
	 *
	 * This function converts a hexadecimal string representation to a Jacobian point.
	 *
	 * @param[out] P Pointer to the Jacobian point that will store the result.
	 * @param[in] hex Hexadecimal string representation (128 characters) of the Jacobian point.
	 */
	void peace_sm2_jacobian_point_from_hex(peace_sm2_JACOBIAN_POINT *P, const char hex[64 * 2]);

	/**
	 * @brief Checks if a Jacobian point is at infinity.
	 *
	 * This function determines whether the specified Jacobian point represents the point at infinity on the elliptic curve.
	 *
	 * @param[in] P Pointer to the Jacobian point.
	 * @return int Returns 1 if the point is at infinity, otherwise returns 0.
	 */
	int peace_sm2_jacobian_point_is_at_infinity(const peace_sm2_JACOBIAN_POINT *P);

	/**
	 * @brief Checks if a Jacobian point lies on the curve.
	 *
	 * This function checks whether the specified Jacobian point satisfies the equation of the elliptic curve.
	 *
	 * @param[in] P Pointer to the Jacobian point.
	 * @return int Returns 1 if the point is on the curve, otherwise returns 0.
	 */
	int peace_sm2_jacobian_point_is_on_curve(const peace_sm2_JACOBIAN_POINT *P);

	/**
	 * @brief Compares a Jacobian point with a hexadecimal representation.
	 *
	 * This function compares the specified Jacobian point with a hexadecimal string representing another point.
	 *
	 * @param[in] P Pointer to the Jacobian point.
	 * @param[in] hex Hexadecimal string representation of the other point (128 characters).
	 * @return int Returns 1 if the points are equal, otherwise returns 0.
	 */
	int peace_sm2_jacobian_point_equ_hex(const peace_sm2_JACOBIAN_POINT *P, const char hex[128]);

	/**
	 * @brief Prints a Jacobian point.
	 *
	 * This function prints the details of the specified Jacobian point to the file stream.
	 *
	 * @param[in] fp File pointer where the output will be written.
	 * @param[in] fmt Format specifier for printing.
	 * @param[in] ind Indentation level for formatting.
	 * @param[in] label Label to prepend to the printed information.
	 * @param[in] P Pointer to the Jacobian point.
	 * @return int Number of characters printed.
	 */
	int peace_sm2_jacobian_point_print(FILE *fp, int fmt, int ind, const char *label, const peace_sm2_JACOBIAN_POINT *P);

/**
 * @brief Copy a Jacobian point.
 *
 * This macro copies the contents of one Jacobian point to another.
 *
 * @param R Destination Jacobian point.
 * @param P Source Jacobian point.
 */
#define peace_sm2_jacobian_point_copy(R, P) memcpy((R), (P), sizeof(peace_sm2_JACOBIAN_POINT))

	/**
	 * @brief Convert octets to an elliptic curve point.
	 *
	 * This function converts the provided octet string to an elliptic curve point.
	 *
	 * @param P Pointer to the elliptic curve point structure where the result will be stored.
	 * @param in Pointer to the input octet string.
	 * @param inlen Length of the input octet string.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_from_octets(peace_sm2_POINT *P, const uint8_t *in, size_t inlen);

	/**
	 * @brief Convert an elliptic curve point to compressed octets.
	 *
	 * This function converts the provided elliptic curve point to a compressed octet string.
	 *
	 * @param P Pointer to the elliptic curve point.
	 * @param out Buffer to store the compressed octet string. Must be at least 33 bytes long.
	 */
	void peace_sm2_point_to_compressed_octets(const peace_sm2_POINT *P, uint8_t out[33]);

	/**
	 * @brief Convert an elliptic curve point to uncompressed octets.
	 *
	 * This function converts the provided elliptic curve point to an uncompressed octet string.
	 *
	 * @param P Pointer to the elliptic curve point.
	 * @param out Buffer to store the uncompressed octet string. Must be at least 65 bytes long.
	 */
	void peace_sm2_point_to_uncompressed_octets(const peace_sm2_POINT *P, uint8_t out[65]);

	/**
	 * @brief Create an elliptic curve point from its X coordinate and Y parity.
	 *
	 * This function creates an elliptic curve point from the given X coordinate and Y parity.
	 *
	 * @param P Pointer to the elliptic curve point structure where the result will be stored.
	 * @param x Pointer to the 32-byte X coordinate.
	 * @param y Parity of the Y coordinate (0 or 1).
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_from_x(peace_sm2_POINT *P, const uint8_t x[32], int y);

	/**
	 * @brief Create an elliptic curve point from its X and Y coordinates.
	 *
	 * This function creates an elliptic curve point from the given X and Y coordinates.
	 *
	 * @param P Pointer to the elliptic curve point structure where the result will be stored.
	 * @param x Pointer to the 32-byte X coordinate.
	 * @param y Pointer to the 32-byte Y coordinate.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_from_xy(peace_sm2_POINT *P, const uint8_t x[32], const uint8_t y[32]);

	/**
	 * @brief Check if an elliptic curve point is on the curve.
	 *
	 * This function checks if the provided elliptic curve point lies on the curve.
	 *
	 * @param P Pointer to the elliptic curve point.
	 * @return int 1 if the point is on the curve, 0 otherwise.
	 */
	int peace_sm2_point_is_on_curve(const peace_sm2_POINT *P);

	/**
	 * @brief Add two elliptic curve points.
	 *
	 * This function adds two elliptic curve points and stores the result in another point.
	 *
	 * @param R Pointer to the resulting elliptic curve point.
	 * @param P Pointer to the first elliptic curve point.
	 * @param Q Pointer to the second elliptic curve point.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_add(peace_sm2_POINT *R, const peace_sm2_POINT *P, const peace_sm2_POINT *Q);

	/**
	 * @brief Subtract one elliptic curve point from another.
	 *
	 * This function subtracts the second elliptic curve point from the first and stores the result in another point.
	 *
	 * @param R Pointer to the resulting elliptic curve point.
	 * @param P Pointer to the first elliptic curve point.
	 * @param Q Pointer to the second elliptic curve point.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_sub(peace_sm2_POINT *R, const peace_sm2_POINT *P, const peace_sm2_POINT *Q);

	/**
	 * @brief Negate an elliptic curve point.
	 *
	 * This function negates the provided elliptic curve point and stores the result in another point.
	 *
	 * @param R Pointer to the resulting elliptic curve point.
	 * @param P Pointer to the elliptic curve point to negate.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_neg(peace_sm2_POINT *R, const peace_sm2_POINT *P);

	/**
	 * @brief Double an elliptic curve point.
	 *
	 * This function doubles the provided elliptic curve point and stores the result in another point.
	 *
	 * @param R Pointer to the resulting elliptic curve point.
	 * @param P Pointer to the elliptic curve point to double.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_dbl(peace_sm2_POINT *R, const peace_sm2_POINT *P);

	/**
	 * @brief Multiply an elliptic curve point by a scalar.
	 *
	 * This function multiplies the provided elliptic curve point by a scalar and stores the result in another point.
	 *
	 * @param R Pointer to the resulting elliptic curve point.
	 * @param k Pointer to the 32-byte scalar value.
	 * @param P Pointer to the elliptic curve point to multiply.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_mul(peace_sm2_POINT *R, const uint8_t k[32], const peace_sm2_POINT *P);

	/**
	 * @brief Multiply the generator point by a scalar.
	 *
	 * This function multiplies the generator point by a scalar and stores the result in another point.
	 *
	 * @param R Pointer to the resulting elliptic curve point.
	 * @param k Pointer to the 32-byte scalar value.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_mul_generator(peace_sm2_POINT *R, const uint8_t k[32]);

	/**
	 * @brief Compute the sum of two scalar multiplications of elliptic curve points.
	 *
	 * This function computes the sum of two scalar multiplications of elliptic curve points: k*P + s*G, where G is the generator point.
	 *
	 * @param R Pointer to the resulting elliptic curve point.
	 * @param k Pointer to the 32-byte scalar value for point P.
	 * @param P Pointer to the first elliptic curve point.
	 * @param s Pointer to the 32-byte scalar value for the generator point.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_mul_sum(peace_sm2_POINT *R, const uint8_t k[32], const peace_sm2_POINT *P, const uint8_t s[32]);

	/**
	 * @brief Convert DER-formatted elliptic curve point to internal representation.
	 *
	 * This function converts the DER-formatted elliptic curve point to the internal representation and stores it in the specified structure.
	 *
	 * @param P Pointer to the elliptic curve point structure where the result will be stored.
	 * @param in Pointer to the pointer that points to the DER-encoded elliptic curve point.
	 * @param inlen Pointer to the variable that contains the length of the DER-encoded elliptic curve point.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_from_der(peace_sm2_POINT *P, const uint8_t **in, size_t *inlen);

	/**
	 * @brief Print elliptic curve point.
	 *
	 * This function prints the elliptic curve point in the specified format and indentation level.
	 *
	 * @param fp File pointer where the output will be written.
	 * @param fmt Format specifier.
	 * @param ind Indentation level.
	 * @param label Label to print before the point.
	 * @param P Pointer to the elliptic curve point.
	 * @return int Number of characters printed on success, -1 on failure.
	 */
	int peace_sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const peace_sm2_POINT *P);

	/**
	 * @brief Create an elliptic curve point from a hash value.
	 *
	 * This function creates an elliptic curve point from the given hash value.
	 *
	 * @param R Pointer to the elliptic curve point structure where the result will be stored.
	 * @param data Pointer to the hash value.
	 * @param datalen Length of the hash value.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_point_from_hash(peace_sm2_POINT *R, const uint8_t *data, size_t datalen);

	/**
	 * @brief Sign a message digest using the SM2 algorithm.
	 *
	 * This function signs the provided message digest using the given SM2 private key and stores the signature in the specified structure.
	 *
	 * @param key Pointer to the SM2 private key.
	 * @param dgst Pointer to the 32-byte message digest to be signed.
	 * @param sig Pointer to the structure where the signature will be stored.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_do_sign(const peace_sm2_KEY *key, const uint8_t dgst[32], peace_sm2_SIGNATURE *sig);

	/**
	 * @brief Sign a message digest using the SM2 algorithm with a fast method.
	 *
	 * This function signs the provided message digest using the given SM2 private key and a fast signing method, storing the signature in the specified structure.
	 *
	 * @param d Fast signing function.
	 * @param dgst Pointer to the 32-byte message digest to be signed.
	 * @param sig Pointer to the structure where the signature will be stored.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_do_sign_fast(const peace_sm2_Fn d, const uint8_t dgst[32], peace_sm2_SIGNATURE *sig);

	/**
	 * @brief Verify a message digest signature using the SM2 algorithm.
	 *
	 * This function verifies the provided message digest signature using the given SM2 public key.
	 *
	 * @param key Pointer to the SM2 public key.
	 * @param dgst Pointer to the 32-byte message digest that was signed.
	 * @param sig Pointer to the signature to be verified.
	 * @return int 1 if the signature is valid, 0 if the signature is invalid or an error occurred.
	 */
	int peace_sm2_do_verify(const peace_sm2_KEY *key, const uint8_t dgst[32], const peace_sm2_SIGNATURE *sig);

/**
 * @brief Minimum size of an SM2 signature.
 */
#define peace_sm2_MIN_SIGNATURE_SIZE 8

/**
 * @brief Maximum size of an SM2 signature.
 */
#define peace_sm2_MAX_SIGNATURE_SIZE 72

	/**
	 * @brief Convert SM2 signature to DER format.
	 *
	 * This function converts the SM2 signature to DER format and stores it in the specified buffer.
	 *
	 * @param sig Pointer to the SM2 signature.
	 * @param out Pointer to the pointer that will receive the allocated buffer containing the DER-encoded signature.
	 * @param outlen Pointer to the variable that will store the length of the DER-encoded signature.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_signature_to_der(const peace_sm2_SIGNATURE *sig, uint8_t **out, size_t *outlen);

	/**
	 * @brief Convert DER-formatted SM2 signature to internal representation.
	 *
	 * This function converts the DER-formatted SM2 signature to the internal representation and stores it in the specified structure.
	 *
	 * @param sig Pointer to the SM2 signature structure where the result will be stored.
	 * @param in Pointer to the pointer that points to the DER-encoded signature.
	 * @param inlen Pointer to the variable that contains the length of the DER-encoded signature.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_signature_from_der(peace_sm2_SIGNATURE *sig, const uint8_t **in, size_t *inlen);

	/**
	 * @brief Print SM2 signature.
	 *
	 * This function prints the SM2 signature in the specified format and indentation level.
	 *
	 * @param fp File pointer where the output will be written.
	 * @param fmt Format specifier.
	 * @param ind Indentation level.
	 * @param label Label to print before the signature.
	 * @param sig Pointer to the signature data.
	 * @param siglen Length of the signature data.
	 * @return int Number of characters printed on success, -1 on failure.
	 */
	int peace_sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen);

	/**
	 * @brief Internal function to sign a message digest using the SM2 algorithm.
	 *
	 * This function internally signs the provided message digest using the given SM2 private key and stores the signature components in the specified buffers.
	 *
	 * @param key Pointer to the SM2 private key.
	 * @param dgst Pointer to the 32-byte message digest to be signed.
	 * @param sigbuf Pointer to the buffer where the complete signature will be stored.
	 * @param sign_R Pointer to the buffer where the R component of the signature will be stored.
	 * @param sign_S Pointer to the buffer where the S component of the signature will be stored.
	 * @param siglen Pointer to the variable that will store the length of the signature.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_sign_internal(const peace_sm2_KEY *key, const uint8_t dgst[32], uint8_t *sigbuf, uint8_t *sign_R, uint8_t *sign_S, size_t *siglen);

	/**
	 * @brief Internal function to verify a message digest signature using the SM2 algorithm.
	 *
	 * This function internally verifies the provided message digest signature using the given SM2 public key.
	 *
	 * @param key Pointer to the SM2 public key.
	 * @param dgst Pointer to the 32-byte message digest that was signed.
	 * @param sig Pointer to the signature to be verified.
	 * @param siglen Length of the signature.
	 * @return int 1 if the signature is valid, 0 if the signature is invalid or an error occurred.
	 */
	int peace_sm2_verify_internal(const peace_sm2_KEY *key, const uint8_t dgst[32], const uint8_t *sig, size_t siglen);

	/**
	 * @brief Sign a message digest using the SM2 algorithm with fixed-length signature.
	 *
	 * This function signs the provided message digest using the given SM2 private key and ensures the signature has a fixed length.
	 *
	 * @param key Pointer to the SM2 private key.
	 * @param dgst Pointer to the 32-byte message digest to be signed.
	 * @param siglen Desired length of the signature.
	 * @param sig Pointer to the buffer where the signature will be stored.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_sign_fixlen(const peace_sm2_KEY *key, const uint8_t dgst[32], size_t siglen, uint8_t *sig);

/**
 * @brief Default ID for SM2 operations.
 */
#define peace_sm2_DEFAULT_ID "1234567812345678"

/**
 * @brief Length of the default ID used in SM2 operations.
 */
#define peace_sm2_DEFAULT_ID_LENGTH (sizeof(peace_sm2_DEFAULT_ID) - 1)

/**
 * @brief Bit length of the default ID used in SM2 operations.
 */
#define peace_sm2_DEFAULT_ID_BITS (peace_sm2_DEFAULT_ID_LENGTH * 8)

/**
 * @brief Maximum bit length of the ID used in SM2 operations.
 */
#define peace_sm2_MAX_ID_BITS 65535

/**
 * @brief Maximum byte length of the ID used in SM2 operations.
 */
#define peace_sm2_MAX_ID_LENGTH (peace_sm2_MAX_ID_BITS / 8)

	/**
	 * @brief Compute the Z value for SM2.
	 *
	 * This function computes the Z value used in the SM2 algorithm based on the public key and the user ID.
	 *
	 * @param z Pointer to the output buffer where the computed Z value will be stored.
	 * @param pub Pointer to the public key.
	 * @param id Pointer to the user ID string.
	 * @param idlen Length of the user ID string.
	 * @return int 1 on success, 0 on failure.
	 */
	int sm2ComputeZ(uint8_t z[32], const peace_sm2_POINT *pub, const char *id, size_t idlen);

	/**
	 * @brief Initialize the SM2 signing context.
	 *
	 * This function initializes the SM2 signing context with the provided key and user ID.
	 *
	 * @param ctx Pointer to the SM2 signing context to initialize.
	 * @param key Pointer to the SM2 key.
	 * @param id Pointer to the user ID string.
	 * @param idlen Length of the user ID string.
	 * @return Std_ReturnType Standard return type indicating success or failure.
	 */
	Std_ReturnType peace_sm2_sign_init(peace_sm2_SIGN_CTX *ctx, const peace_sm2_KEY *key, const char *id, size_t idlen);

	/**
	 * @brief Update the SM2 signing context with data.
	 *
	 * This function updates the SM2 signing context with the provided data.
	 *
	 * @param ctx Pointer to the SM2 signing context.
	 * @param data Pointer to the data to update the context with.
	 * @param datalen Length of the data.
	 * @return Std_ReturnType Standard return type indicating success or failure.
	 */
	Std_ReturnType peace_sm2_sign_update(peace_sm2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);

	/**
	 * @brief Finalize the SM2 signing process.
	 *
	 * This function finalizes the SM2 signing process and produces the signature.
	 *
	 * @param ctx Pointer to the SM2 signing context.
	 * @param sig Pointer to the output buffer where the signature will be stored.
	 * @param Sig_R Pointer to the R component of the signature.
	 * @param Sig_S Pointer to the S component of the signature.
	 * @param siglen Pointer to the variable that will store the length of the signature.
	 * @return Std_ReturnType Standard return type indicating success or failure.
	 */
	Std_ReturnType peace_sm2_sign_finish(peace_sm2_SIGN_CTX *ctx, uint8_t *sig, uint8_t *Sig_R, uint8_t *Sig_S, size_t *siglen);

	/**
	 * @brief Finalize the SM2 signing process with a fixed-length signature.
	 *
	 * This function finalizes the SM2 signing process and produces a fixed-length signature.
	 *
	 * @param ctx Pointer to the SM2 signing context.
	 * @param siglen Length of the fixed-length signature.
	 * @param sig Pointer to the output buffer where the fixed-length signature will be stored.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_sign_finish_fixlen(peace_sm2_SIGN_CTX *ctx, size_t siglen, uint8_t *sig);

	/**
	 * @brief Initialize the SM2 verification context.
	 *
	 * This function initializes the SM2 verification context with the provided key and user ID.
	 *
	 * @param ctx Pointer to the SM2 verification context to initialize.
	 * @param key Pointer to the SM2 key.
	 * @param id Pointer to the user ID string.
	 * @param idlen Length of the user ID string.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_verify_init(peace_sm2_SIGN_CTX *ctx, const peace_sm2_KEY *key, const char *id, size_t idlen);

	/**
	 * @brief Update the SM2 verification context with data.
	 *
	 * This function updates the SM2 verification context with the provided data.
	 *
	 * @param ctx Pointer to the SM2 verification context.
	 * @param data Pointer to the data to update the context with.
	 * @param datalen Length of the data.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_verify_update(peace_sm2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);

	/**
	 * @brief Finalize the SM2 verification process.
	 *
	 * This function finalizes the SM2 verification process and verifies the signature.
	 *
	 * @param ctx Pointer to the SM2 verification context.
	 * @param sig Pointer to the signature to verify.
	 * @param siglen Length of the signature.
	 * @return int 1 if the signature is valid, 0 if invalid.
	 */
	int peace_sm2_verify_finish(peace_sm2_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen);
	;

	/**
	 * @brief Encrypt data using the SM2 algorithm.
	 *
	 * This function encrypts the input data using the provided SM2 key and stores the ciphertext in the specified structure.
	 *
	 * @param key Pointer to the SM2 key.
	 * @param in Pointer to the input data to be encrypted.
	 * @param inlen Length of the input data.
	 * @param out Pointer to the structure where the ciphertext will be stored.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_do_encrypt(const peace_sm2_KEY *key, const uint8_t *in, size_t inlen, peace_sm2_CIPHERTEXT *out);

	/**
	 * @brief Decrypt data using the SM2 algorithm.
	 *
	 * This function decrypts the ciphertext using the provided SM2 key and stores the plaintext in the specified buffer.
	 *
	 * @param key Pointer to the SM2 key.
	 * @param in Pointer to the ciphertext to be decrypted.
	 * @param out Pointer to the buffer where the plaintext will be stored.
	 * @param outlen Pointer to the variable that will store the length of the plaintext.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_do_decrypt(const peace_sm2_KEY *key, const peace_sm2_CIPHERTEXT *in, uint8_t *out, size_t *outlen);

/**
 * @brief Minimum size of an SM2 ciphertext.
 */
#define peace_sm2_MIN_CIPHERTEXT_SIZE 45

/**
 * @brief Maximum size of an SM2 ciphertext.
 */
#define peace_sm2_MAX_CIPHERTEXT_SIZE 366

	/**
	 * @brief Convert SM2 ciphertext to DER format.
	 *
	 * This function converts the SM2 ciphertext to DER format and stores it in the specified buffer.
	 *
	 * @param c Pointer to the SM2 ciphertext.
	 * @param out Pointer to the pointer that will receive the allocated buffer containing the DER-encoded ciphertext.
	 * @param outlen Pointer to the variable that will store the length of the DER-encoded ciphertext.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_ciphertext_to_der(const peace_sm2_CIPHERTEXT *c, uint8_t **out, size_t *outlen);

	/**
	 * @brief Convert DER-formatted SM2 ciphertext to internal representation.
	 *
	 * This function converts the DER-formatted SM2 ciphertext to the internal representation and stores it in the specified structure.
	 *
	 * @param c Pointer to the SM2 ciphertext structure where the result will be stored.
	 * @param in Pointer to the pointer that points to the DER-encoded ciphertext.
	 * @param inlen Pointer to the variable that contains the length of the DER-encoded ciphertext.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_ciphertext_from_der(peace_sm2_CIPHERTEXT *c, const uint8_t **in, size_t *inlen);

	/**
	 * @brief Print SM2 ciphertext.
	 *
	 * This function prints the SM2 ciphertext in the specified format and indentation level.
	 *
	 * @param fp File pointer where the output will be written.
	 * @param fmt Format specifier.
	 * @param ind Indentation level.
	 * @param label Label to print before the ciphertext.
	 * @param a Pointer to the ciphertext data.
	 * @param alen Length of the ciphertext data.
	 * @return int Number of characters printed on success, -1 on failure.
	 */
	int peace_sm2_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);

	/**
	 * @brief Encrypt data using the SM2 algorithm (convenience wrapper).
	 *
	 * This function encrypts the input data using the provided SM2 key and stores the ciphertext in the specified buffer.
	 *
	 * @param key Pointer to the SM2 key.
	 * @param in Pointer to the input data to be encrypted.
	 * @param inlen Length of the input data.
	 * @param out Pointer to the buffer where the ciphertext will be stored.
	 * @param outlen Pointer to the variable that will store the length of the ciphertext.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_encrypt(const peace_sm2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);

	/**
	 * @brief Decrypt data using the SM2 algorithm (convenience wrapper).
	 *
	 * This function decrypts the ciphertext using the provided SM2 key and stores the plaintext in the specified buffer.
	 *
	 * @param key Pointer to the SM2 key.
	 * @param in Pointer to the ciphertext to be decrypted.
	 * @param inlen Length of the ciphertext.
	 * @param out Pointer to the buffer where the plaintext will be stored.
	 * @param outlen Pointer to the variable that will store the length of the plaintext.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_decrypt(const peace_sm2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);

	/**
	 * @brief Encrypt data using the SM2 algorithm with fixed-length point size.
	 *
	 * This function encrypts the input data using the provided SM2 key and a fixed-length point size, storing the ciphertext in the specified structure.
	 *
	 * @param key Pointer to the SM2 key.
	 * @param in Pointer to the input data to be encrypted.
	 * @param inlen Length of the input data.
	 * @param point_size Fixed length of the point size.
	 * @param out Pointer to the structure where the ciphertext will be stored.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_do_encrypt_fixlen(const peace_sm2_KEY *key, const uint8_t *in, size_t inlen, int point_size, peace_sm2_CIPHERTEXT *out);

	/**
	 * @brief Encrypt data using the SM2 algorithm with fixed-length point size (convenience wrapper).
	 *
	 * This function encrypts the input data using the provided SM2 key and a fixed-length point size, storing the ciphertext in the specified buffer.
	 *
	 * @param key Pointer to the SM2 key.
	 * @param in Pointer to the input data to be encrypted.
	 * @param inlen Length of the input data.
	 * @param point_size Fixed length of the point size.
	 * @param out Pointer to the buffer where the ciphertext will be stored.
	 * @param outlen Pointer to the variable that will store the length of the ciphertext.
	 * @return int 1 on success, 0 on failure.
	 */
	int peace_sm2_encrypt_fixlen(const peace_sm2_KEY *key, const uint8_t *in, size_t inlen, int point_size, uint8_t *out, size_t *outlen);


#ifdef __cplusplus
}
#endif
#endif
